package iu.grafico;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import magnata.Magnata;
import magnata.Player;

class PlayerData extends JPanel implements Observer {

    JLabel victoryMessage = new JLabel("GANHOU!!");
    JLabel name = new JLabel();

    JPanel hand = new JPanel() {
        public void paintBorder(Graphics g) {
            super.paintBorder(g);
            g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
//			PlayerData p;
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            //int pecasMao = jogador.getNumPecas();
            int comprimento = (getWidth() / 3);
            int altura = getHeight();
            int lado = (comprimento > altura) ? altura : comprimento;
            int margem = 5;
//            for (int i = 0; i < pecasMao; i++) {
//                g.drawImage(GameCell.getPlayerIcon(jogador, jogo), (i * lado) + margem, margem, lado - 2 * margem, lado - 2 * margem, null);
//            }
        }
    };
    Magnata jogo;
    Player jogador;

    PlayerData(Magnata jogo, Player j) {
        this.jogo = jogo;
        jogador = j;
        setupLayout();
        registerObservers();
    }

    private void registerObservers() {
        jogo.addObserver(this);
    }

    private void setupLayout() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        //name.setText(jogador.get_PlayerName().toString());
        name.setText("Jogador");
        name.setAlignmentY(CENTER_ALIGNMENT);
        hand.setAlignmentY(CENTER_ALIGNMENT);
        hand.setBackground(Color.WHITE);
        victoryMessage.setVisible(false);
        victoryMessage.setFont(new Font("Dialog", Font.BOLD, 30));
        name.setAlignmentX(CENTER_ALIGNMENT);
        victoryMessage.setAlignmentX(CENTER_ALIGNMENT);
        add(name);
        add(victoryMessage);
        add(hand);
        if (jogo.getCurrentPlayer() == jogador) {
            setBackground(Color.YELLOW);
        } else {
            setBackground(Color.gray);
        }
    }

    public void paintBorder(Graphics g) {
        super.paintBorder(g);
        if (jogo.getCurrentPlayer() == jogador) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setStroke(new BasicStroke(8));  //espessura da linha
            g2.setColor(Color.GREEN);
            g2.drawRect(0, 0, getWidth(), getHeight());
        }
    }

    @Override
    public void update(Observable arg0, Object arg1) {
        name.setText(jogador.get_PlayerName());
        validate();
        if (jogo != null) {
//            if (jogo.) {
//                hand.setVisible(false);
//                victoryMessage.setVisible(jogo.ganhou(jogador));
//            } else {
//                hand.setVisible(true);
//                victoryMessage.setVisible(false);
//            }
        }
        if (jogo.getCurrentPlayer() == jogador) {
            setBackground(Color.YELLOW);
        } else {
            setBackground(Color.gray);
        }
        repaint();
    }
}

class PlayerNameBox extends JPanel implements Observer {

    int nr;
    Magnata jogo;
    JTextField nameField;

    PlayerNameBox(Magnata j, int playerNr) {
        nameField = new JTextField(15);
        //String nome = (playerNr == 1) ? j.getPlayers().get(0).get_PlayerName() : j.getPlayers().get(1).get_PlayerName();
        String nome = "Jogador";
        nameField.setText(nome);
        setMaximumSize(new Dimension(200, 40));
        jogo = j;
        nr = playerNr;
        //setVisible(nr <= jogo.getNumJog());
        setupLayout();

        // Listen for changes in the text
        nameField.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void changedUpdate(DocumentEvent e) {
                //jogo.getPlayers().(nr, nameField.getText());
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                //jogo.defineNomeJogador(nr, nameField.getText());
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
            	//jogo.defineNomeJogador(nr, nameField.getText());
            }
        });
    }

    private void setupLayout() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        add(new JLabel("Player" + nr + " Name"));
        add(nameField);
    }

    public void update(Observable obs, Object o) {
        //setVisible(nr <= jogo.getNumJog());
        getParent().validate();  //valida o contentor deste componente

    }

    public String getText() {
        return nameField.getText();
    }
}

class OptionPanel extends JPanel implements Observer {

    JButton start = new JButton("Start");
    Magnata jogo;
    JComboBox<String> playerNrBox;
    JComboBox<String> aiPlayerLevel;
    PlayerNameBox player1Name;
    PlayerNameBox player2Name;
    String[] playerNumberStrings = {"AI vs AI", "Human vs AI", "Human vs. Human"};
    String[] aiPlayerLevelStrings = {"Random", "Easy", "Normal", "Master"};
    int aiLevelOption = 1;

//    private Observer getAI(int level, Magnata jogo, Player jogador) {
//        if (aiLevelOption == 0) {
//            //return new EmLinhaIA(jogador, jogo);
//        } else {
//            //return new EmLinhaIASmartish(jogador, jogo, 2 * aiLevelOption + (aiLevelOption == 3 ? 2 : 0));
//        }
//
//    }

    OptionPanel(Magnata j) {
        jogo = j;
        setBackground(Color.GREEN);
        setupComponents();
        setupLayout();
        registerObservers();
        //setVisible(jogo.getEstado() instanceof AguardaInicio);
        setVisible(true);
    }

    void registerObservers() {
        jogo.addObserver(player1Name);
        jogo.addObserver(player2Name);
        jogo.addObserver(this);
    }

    private void setupLayout() {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

        JPanel top = new JPanel();

        top.add(start);
        top.add(playerNrBox);
        top.setMaximumSize(new Dimension(300, 60));
        add(top);
        add(aiPlayerLevel);
        add(player1Name);
        add(player2Name);

        player1Name.setMinimumSize(new Dimension(120, 20));
        player2Name.setMinimumSize(new Dimension(120, 20));
        top.setAlignmentX(Component.CENTER_ALIGNMENT);
        player1Name.setAlignmentX(Component.CENTER_ALIGNMENT);
        player2Name.setAlignmentX(Component.CENTER_ALIGNMENT);
        player1Name.setOpaque(false);
        player2Name.setOpaque(false);
        top.setOpaque(false);
        validate();
    }
    ArrayList<Observer> ias = new ArrayList<Observer>();

    private void flushCurrentIA() {
        for (Observer ia : ias) {
            jogo.deleteObserver(ia);
        }
        ias.clear();
    }

//    private void addNewIA(Observer ia) {
//        ias.add(ia);
//    }

    private void setupComponents() {
        player1Name = new PlayerNameBox(jogo, 1);
        player2Name = new PlayerNameBox(jogo, 2);

        start.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                flushCurrentIA();
                //jogo.getPlayers().(1, player1Name.getText());
                //jogo.defineNomeJogador(2, player2Name.getText());
//                if (jogo.getNumJog() < 2) {
//                    jogo.defineNomeJogador(2, "IA");
//                    addNewIA(getAI(aiLevelOption, jogo, jogo.getJogador2()));
//                    //	new EmLinhaIASmartish(jogo.getJogador2(),jogo));
//                }
//                if (jogo.getNumJog() < 1) {
//                    jogo.defineNomeJogador(2, "IA-2");
//                    jogo.defineNomeJogador(1, "IA-1");
//                    addNewIA(new EmLinhaIA(jogo.getJogador1(), jogo));
//                }
                //jogo.setupGame();

            }
        });

        playerNrBox = new JComboBox<String>(playerNumberStrings);
        playerNrBox.setSelectedIndex(1);
        playerNrBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                int option = playerNrBox.getSelectedIndex();
                //jogo.defineNumeroJogadores(option);

            }
        });

        aiPlayerLevel = new JComboBox<String>(aiPlayerLevelStrings);
        aiPlayerLevel.setMaximumSize(new Dimension(200, 20));
        aiPlayerLevel.setSelectedIndex(1);
        //aiPlayerLevel.setVisible(jogo.getNumJog() == 1);
        aiPlayerLevel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                aiLevelOption = aiPlayerLevel.getSelectedIndex();
                System.out.println("escolhi nivel " + aiLevelOption);
            }
        });

    }

    @Override
    public void update(Observable arg0, Object arg1) {
        //aiPlayerLevel.setVisible(jogo.getNumJog() == 1);
        //setVisible(jogo.getEstado() instanceof AguardaInicio);
        setVisible(true);
        getParent().validate();

    }
}


class GameCell extends JPanel implements Observer {

    int row, col;
    Magnata jogo;
    static String imageFiles[] = {"sun.gif", "moon.png"};
    static Image playerIcons[] = new Image[2];
    static boolean imagesLoaded = false;

    /**
     * f�brica de objectos que devolve imagem associada a cada jogador de um
     * jogo
     *
     * @param jogador
     * @param jogo
     * @return
     */
    static Image getPlayerIcon(Player jogador, Magnata jogo) {
        if (!imagesLoaded) {
            int i = 0;
            imagesLoaded = true;
            for (String fileName : imageFiles) {
                try {
                    playerIcons[i++] = ImageIO.read(new File(fileName));
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
        }

        if (jogo.getPlayers().get(0) == jogador) {
            return playerIcons[0];
        } else {
            return playerIcons[1];
        }
    }

    GameCell(Magnata j, int r, int c) {
        row = r;
        col = c;
        this.jogo = j;

        setPreferredSize(new Dimension(100, 100));
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent ev) {

//                if (jogo.getEstado() instanceof AguardaColocacao) {
//                    jogo.jogar(row, col);
//                } else {
//                    jogo.devolver(row, col);
//                }
            }
        });
    }

    public void paintBorder(Graphics g) {
        super.paintBorder(g);
        g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
    }

    public void paintComponent(Graphics g) {
//        if (jogo.getEstado() instanceof AguardaInicio) {
//            setBackground(Color.LIGHT_GRAY);
//        } else {
//            setBackground(Color.WHITE);
//        }

        super.paintComponent(g);
//        Peca p = jogo.getPeca(row, col);
//        if (p == null) {
//            return;
//        }
        //Player j = p.getJogador();
        //drawIcon(j, g);

    }

    private void drawIcon(Player j, Graphics g) {
        Image img = getPlayerIcon(j, jogo);
        g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
    }

    @Override
    public void update(Observable o, Object arg) {
        repaint();
    }
}


class GameGrid extends JPanel {

    Magnata jogo;
    ArrayList<GameCell> cells = new ArrayList<GameCell>();

    GameGrid(Magnata j) {
        jogo = j;
        System.out.println(this + " " + jogo);
        setupLayout();

    }

    void registerObservers() {
        for (GameCell cell : cells) {
            jogo.addObserver(cell);
        }

    }

    void setupLayout() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        for (int i = 0; i < 3; i++) {
            JPanel p = new JPanel();
            for (int j = 0; j < 3; j++) {
                GameCell cell = new GameCell(jogo, i, j);
                cells.add(cell);
                p.add(cell);
            }
            add(p);
        }

    }
};


public class PainelMagnata extends JPanel {
	Magnata jogo;
	OptionPanel optionPanel;
	GameGrid theGrid;
	PlayerData pd1, pd2;
	
	public PainelMagnata (Magnata j) {
		jogo = j;
		System.out.println(j);
		setLayout(new BorderLayout());
        setupComponents();
        setupLayout();
        registerObservers();
	}
	
	private void setupComponents() {
        optionPanel = new OptionPanel(jogo);
        theGrid = new GameGrid(jogo);
        pd1 = new PlayerData(jogo, jogo.getCurrentPlayer());
        pd2 = new PlayerData(jogo, jogo.getCurrentPlayer());
    }
	
	private void setupLayout() {
        JPanel centro = new JPanel();
        centro.setLayout(new BorderLayout());
        add(optionPanel, BorderLayout.EAST);
        centro.add(theGrid, BorderLayout.NORTH);

        add(centro, BorderLayout.CENTER);
        JPanel sul = new JPanel();
        sul.add(pd1);
        sul.add(pd2);
        pd1.setPreferredSize(new Dimension(200, 80));
        pd2.setPreferredSize(new Dimension(200, 80));
        centro.add(sul, BorderLayout.SOUTH);
        validate();
    }
	
    private void registerObservers() {
        optionPanel.registerObservers();
        theGrid.registerObservers();
    }
}
